add privileged/unprivileged kernel feature indication
authorJan Beulich <jbeulich@novell.com>
Fri, 8 Jul 2011 07:34:29 +0000 (08:34 +0100)
committerJan Beulich <jbeulich@novell.com>
Fri, 8 Jul 2011 07:34:29 +0000 (08:34 +0100)
With our switching away from supporting 32-bit Dom0 operation, users
complained that attempts (perhaps due to lack of knowledge of that
change) to boot the no longer privileged kernel in Dom0 resulted in
apparently silent failure. To make the mismatch explicit and visible,
add feature flags that the kernel can set to indicate operation in
what modes it supports. For backward compatibility, absence of both
feature flags is taken to indicate a kernel that may be capable of
operating in both modes.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
tools/libxc/xc_dom_elfloader.c
xen/arch/ia64/xen/domain.c
xen/arch/x86/domain_build.c
xen/common/kernel.c
xen/common/libelf/libelf-dominfo.c
xen/include/public/features.h

index 9114bfb333a8a7da97129b46eaf0d74d80ef77cd..3ddb1dfa28fcbbcdf5d0059709eee1ff71e347a5 100644 (file)
@@ -286,6 +286,15 @@ static int xc_dom_parse_elf_kernel(struct xc_dom_image *dom)
     if ( (rc = elf_xen_parse(elf, &dom->parms)) != 0 )
         return rc;
 
+    if ( elf_xen_feature_get(XENFEAT_privileged, dom->parms.f_required) ||
+         (elf_xen_feature_get(XENFEAT_privileged, dom->parms.f_supported) &&
+          !elf_xen_feature_get(XENFEAT_unprivileged, dom->parms.f_supported)) )
+    {
+        xc_dom_panic(dom->xch, XC_INVALID_KERNEL, "%s: Kernel does not"
+                     " support unprivileged (DomU) operation", __FUNCTION__);
+        return -EINVAL;
+    }
+
     /* find kernel segment */
     dom->kernel_seg.vstart = dom->parms.virt_kstart;
     dom->kernel_seg.vend   = dom->parms.virt_kend;
index 271a744e872736358a5bb90ec143756eb28e4eeb..f6d27e837bba914e20cefe30f9ccf4a2abb323ba 100644 (file)
@@ -2164,6 +2164,14 @@ int __init construct_dom0(struct domain *d,
                return -1;
        }
 
+       if (test_bit(XENFEAT_unprivileged, parms.f_required) ||
+           (test_bit(XENFEAT_unprivileged, parms.f_supported) &&
+            !test_bit(XENFEAT_privileged, parms.f_supported)))
+       {
+               printk("Kernel does not support Dom0 operation\n");
+               return -1;
+       }
+
        p_start = parms.virt_base;
        pkern_start = parms.virt_kstart;
        pkern_end = parms.virt_kend;
index cbb92699f764a2c3228a6e7238a4c4ea980259d7..d4787a79f27d3bab7c9254e1b4e748db4bca363a 100644 (file)
@@ -415,6 +415,14 @@ int __init construct_dom0(
         return -EINVAL;
     }
 
+    if ( test_bit(XENFEAT_unprivileged, parms.f_required) ||
+         (test_bit(XENFEAT_unprivileged, parms.f_supported) &&
+          !test_bit(XENFEAT_privileged, parms.f_supported)) )
+    {
+        printk("Kernel does not support Dom0 operation\n");
+        return -EINVAL;
+    }
+
 #if defined(__x86_64__)
     if ( compat32 )
     {
index 5558dc0712ab81eb1a65e6251e519c90567e05cb..45c900e335b7fe33e231eba8fb8c822f1be14b09 100644 (file)
@@ -278,7 +278,8 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
         switch ( fi.submap_idx )
         {
         case 0:
-            fi.submap = 0;
+            fi.submap = 1U << (IS_PRIV(current->domain) ?
+                               XENFEAT_privileged : XENFEAT_unprivileged);
             if ( VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3) )
                 fi.submap |= (1U << XENFEAT_pae_pgdir_above_4gb);
             if ( paging_mode_translate(current->domain) )
index 29c3339088f1a2eb490357e7e30ad7cbc1193510..5f48d3fea31f0747259df252166ae8932360ac1f 100644 (file)
@@ -26,7 +26,9 @@ static const char *const elf_xen_feature_names[] = {
     [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
     [XENFEAT_auto_translated_physmap] = "auto_translated_physmap",
     [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel",
-    [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
+    [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb",
+    [XENFEAT_privileged] = "privileged",
+    [XENFEAT_unprivileged] = "unprivileged"
 };
 static const int elf_xen_features =
 sizeof(elf_xen_feature_names) / sizeof(elf_xen_feature_names[0]);
index 0e3c48624932cf3fcc888cbd06744021fb3a49a8..6298e2d11c6ed551e771bd3481a8720238703b51 100644 (file)
 #define XENFEAT_hvm_safe_pvclock           9
 
 /* x86: pirq can be used by HVM guests */
-#define XENFEAT_hvm_pirqs           10
+#define XENFEAT_hvm_pirqs                 10
+
+/* privileged operation is supported */
+#define XENFEAT_privileged                11
+
+/* un-privileged operation is supported */
+#define XENFEAT_unprivileged              12
 
 #define XENFEAT_NR_SUBMAPS 1